using System.Reflection;
using System;
using System.IO;
namespace IrisGenerator.Common.Modules
{
    
    
    public partial class ModuleInstance {

        public ModuleBase Instance { get; set; }

        //public override bool Analyse() { return false; }

        //public override bool Generate() { return false; }



        //private ModuleInstance _instance = null;
        //public ModuleInstance Instance
        //{
        //    get
        //    {
        //        if (this._instance == null)
        //        {
        //            if (this.ModInsId.HasValue)
        //                this.Instance = ModuleInstance.Load(this.ModInsId);
        //        }
        //        else
        //        {
        //            if (this._instance.ModInsId.HasValue)
        //            {
        //                if (this._instance.ModInsId.Equals(this.ModInsId))
        //                    return this._instance;
        //                else
        //                    this.Instance = ModuleInstance.Load(this.ModInsId);
        //            }
        //            else
        //            {
        //                if (this.ModInsId.HasValue)
        //                    this.Instance = ModuleInstance.Load(this.ModInsId);
        //            }
        //        }
        //        return this._instance;
        //    }
        //    set
        //    {
        //        _instance = value;
        //        if (value == null)
        //            this.ModInsId = null;
        //        else
        //            this.ModInsId = value.ModInsId;
        //    }
        //}

        public void CreateInstance()
        {
            //TODO: Improve method. How to handle assemblies? Table in the DB?
            if (this.Module == null)
                throw new Exception("No base module for the module instance");

            if (string.IsNullOrEmpty(this.Module.ModAssembly))
                return;

            string[] assembly = this.Module.ModAssembly.Split(",".ToCharArray());
            if (assembly.Length == 0)
                return;

            string fileName = assembly[0] + ".dll";

            fileName = GetAssemblyFileName(fileName);

            if (string.IsNullOrEmpty(fileName))
                return;

            Assembly assemblyFile = Assembly.LoadFrom(fileName);
            Type moduleType = assemblyFile.GetType(this.Module.ModType);
            this.Instance =
                moduleType.InvokeMember("new", BindingFlags.CreateInstance,
                null, this.Instance, null) as ModuleBase;

            foreach (ModuleParameter parameter in this.Module.ModuleParameterCollection)
            {
                ModuleParameterInstance inst =
                    ModuleParameterInstance.Select_MODULE_PARAMETER_INSTANCE_By_MOD_PAR_ID(parameter.ModParId, this.ModInsId);

                if (inst == null)
                {
                    inst = new ModuleParameterInstance();
                    inst.ModuleParameter = parameter;
                    inst.ModuleInstance = this;
                    inst.Insert();
                }
                this.ModuleParameterInstanceCollection.Add(inst);

                this.Instance.ParametersInstances.Add(inst.ModuleParameter.ModParName, inst);

                if (!inst.ModParInsValue.HasValue)
                {
                    foreach (ModuleInstance modInst in this.Project.ModuleInstanceCollection)
                    {
                        if (!modInst.ModInsId.Equals(this.ModInsId))
                        {
                            foreach (ModuleParameterInstance modParamInst in modInst.ModuleParameterInstanceCollection)
                            {
                                if (modParamInst.ModuleParameter.ModParName.Equals(inst.ModuleParameter.ModParName)
                                    && !modParamInst.ModParInsId.Equals(inst.ModParInsId))
                                {
                                    inst.ModParInsValue = modParamInst.ModParInsId;
                                    inst.Update();
                                }
                            }
                        }
                        
                    }
                }
            }
        }

        private string GetAssemblyFileName(string fileName)
        {
            if (string.IsNullOrEmpty(fileName))
                return null;

            string path = Path.GetDirectoryName(this.GetType().Assembly.Location);

            string fullPath = Path.Combine(path, fileName);
            if (File.Exists(fullPath))
                return fullPath;


            return null;
        }

    }
}
